package com.obelisco.vista.componentes;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import nextapp.echo2.app.Alignment;
import nextapp.echo2.app.Column;
import nextapp.echo2.app.Component;
import nextapp.echo2.app.Extent;
import nextapp.echo2.app.Font;
import nextapp.echo2.app.ImageReference;
import nextapp.echo2.app.Insets;
import nextapp.echo2.app.ResourceImageReference;
import nextapp.echo2.app.Table;
import nextapp.echo2.app.event.ActionEvent;
import nextapp.echo2.app.event.ActionListener;
import nextapp.echo2.app.event.TableModelEvent;
import nextapp.echo2.app.event.TableModelListener;
import nextapp.echo2.app.layout.ColumnLayoutData;
import nextapp.echo2.app.layout.TableLayoutData;
import nextapp.echo2.app.list.DefaultListSelectionModel;
import nextapp.echo2.app.list.ListSelectionModel;
import nextapp.echo2.app.table.TableCellRenderer;
import nextapp.echo2.app.table.TableColumn;
import nextapp.echo2.app.table.TableColumnModel;

import org.apache.commons.beanutils.MethodUtils;

import com.jgoodies.binding.adapter.echo.AbstractTableAdapter;
import com.obelisco.vista.controles.Button;
import com.obelisco.vista.controles.DateField;
import com.obelisco.vista.controles.Label;
import com.obelisco.vista.controles.ListBox;
import com.obelisco.vista.controles.SelectField;

import echopointng.BorderEx;
import echopointng.ContainerEx;
import echopointng.ExtentEx;
import echopointng.table.DefaultPageableSortableTableModel;
import echopointng.table.PageableSortableTable;
import echopointng.table.PageableTableNavigation;
import echopointng.table.SortableTableHeaderRenderer;
import echopointng.table.SortableTableModel;

public class TablaDatos extends ContainerEx {

	private PageableSortableTable tabla;
	private  AbstractTableAdapter adapter;
	private  DefaultPageableSortableTableModel modeloTabla;
	private PageableTableNavigation tableScroller;
	private DefaultListSelectionModel defaultListSelectionModel;
	
	private boolean isMultiple = false;
	private int filaSeleccionada = -1;
	private Component container;
	
	
	public TablaDatos() {
		super();
		configurarControles();
	}
	

	private ActionListener tablaActionListener = new ActionListener(){

		public void actionPerformed(ActionEvent e) {
			filaSeleccionada = tabla.getSelectionModel().getMinSelectedIndex();
			filaSeleccionada = modeloTabla.toUnsortedModelRowIndex(filaSeleccionada);
			if (tabla.getSelectionModel().getMinSelectedIndex() == tabla.getSelectionModel().getMaxSelectedIndex())
			{
				isMultiple = false;
			}
			else
			{
				isMultiple = true;			
			}
		}		
	};
	
	private TableModelListener tableModelListener = new TableModelListener(){
    	private boolean isSorted = false;
    	List listaSeleccionados = new ArrayList();
    	
    	public void tableChanged(TableModelEvent arg0) {
    		if (hayRegistrosSeleccionados())
    		{
    			if (!isSorted)
    			{
    				isSorted = true;
    				listaSeleccionados.clear();
	    			for (int i = tabla.getSelectionModel().getMinSelectedIndex(); i <= tabla.getSelectionModel().getMaxSelectedIndex(); i++)
	    			{    				
	    				if (tabla.getSelectionModel().isSelectedIndex(i))
	    				{
	    					Integer indice = new Integer(i);
	    					listaSeleccionados.add(indice);    					
	    				}    				
	    			}
    			}
    			
    			if (modeloTabla.getCurrentSortColumn() == -1)
    			{
    				isSorted = false;
    			}
    			
    			defaultListSelectionModel.clearSelection();
    			for (int i = 0; i < listaSeleccionados.size(); i++)
    			{
    				int indiceInt = ((Integer)listaSeleccionados.get(i)).intValue();
    				if (isSorted)
    				{
	    				defaultListSelectionModel.setSelectedIndex(modeloTabla.toSortedViewRowIndex(indiceInt), true);    				
    				}
    				else
    				{
    					defaultListSelectionModel.setSelectedIndex(indiceInt, true);
    				}
    			}    			
    		}
		}
    };
	
	private SortableTableHeaderRenderer encabezadoTableCellRenderer = new SortableTableHeaderRenderer() {

		private ImageReference upArrowImage = new ResourceImageReference("/echopointng/resource/images/ArrowUp.gif");	   
	    private ImageReference downArrowImage = new ResourceImageReference("/echopointng/resource/images/ArrowDown.gif");	    
	    //private Color background = new Color(0x69829D);
	    //private Color colorLetra = new Color(0xFFFFFF);	   
	    //private BorderEx border = new BorderEx(background);
	    private Insets insets = new Insets( 1 );	    
	    private TableLayoutData layoutData = new TableLayoutData();
	   	    
		protected Button getSortButton( String label, int column, SortableTableModel model) {
			
			ImageReference icon = null;
	        if (model.getCurrentSortColumn() == column) {
	            int sortDirective = model.getSortDirective(column);
	            if (sortDirective == SortableTableModel.ASCENDING){
	                icon = upArrowImage;
	            } else if (sortDirective == SortableTableModel.DESCENDING){
	                icon = downArrowImage;
	            } else {
	                icon = null;
	            }
	        }
	        
	        Button button = new Button(icon);
	        button.setStyleName("Obelisco.Boton.TablaDatos");
	        button.setText(label);
	        button.addActionListener(getSortButtonListener(column,model));
	        //layoutData.setBackground( background );
	        //layoutData.setAlignment(new Alignment(Alignment.CENTER, Alignment.CENTER));
	        //button.setLayoutData( layoutData );
	        //button.setInsets( insets );
	        //button.setBorder( border );
	        //button.setForeground( colorLetra );
	        button.setTextPosition(new Alignment(Alignment.LEFT, Alignment.DEFAULT));
	        
	        return button;
	    }		
    };
    
    private TableCellRenderer tableCellRenderer = new TableCellRenderer() {
        
        public Component getTableCellRendererComponent(Table table, Object value, int column, int row) {
        	TableLayoutData layoutData = new TableLayoutData();        	
        	Object[] tipoColumnas=null;
        	Object[] modoColumnas=null;
        	Component componente=null;
        	Map itemSeleccionadoRender=null;
        	try 
        	{
				tipoColumnas = (Object[])MethodUtils.invokeMethod(adapter,"getCOLUMN_TYPES",null);				
				modoColumnas = (Object[])MethodUtils.invokeMethod(adapter,"getCOLUMN_MODO",null);
				itemSeleccionadoRender = (Map)MethodUtils.invokeMethod(adapter,"getItemSeleccionadosRender",null);
			} 
        	catch (Exception e) 
        	{        	
			}

        	//modocebra(layoutData, row);
        	String nombreEstilo =  modocebra(row);
        	
        	
        	if (modoColumnas != null)
        	{
        		if (modoColumnas[column] == "CENTER" )
        		{
        			layoutData.setAlignment(new Alignment(Alignment.CENTER, Alignment.CENTER));
        		}
        		else if (modoColumnas[column] == "LEFT" || modoColumnas[column] == null)
        		{
        			layoutData.setAlignment(new Alignment(Alignment.LEFT, Alignment.CENTER));
        		} 
        		else if (modoColumnas[column] == "RIGHT")
        		{
        			layoutData.setAlignment(new Alignment(Alignment.RIGHT, Alignment.CENTER ));
        		}        		        		
        	}
        	
        	if (tipoColumnas != null)
        	{
        		if (tipoColumnas[column] == Label.class || tipoColumnas[column] == null)
	        	{
        			Label label = new Label(value.toString());
        			label.setStyleName(nombreEstilo);
	        		label.setLayoutData(layoutData);
        			//label.setStyleName(nombreEstilo);
	        		componente = label;
	        	}     		
        		else if (tipoColumnas[column] instanceof SelectField)
	        	{	        		
	        		SelectField selectField = new SelectField(100);
	        		SelectField aux = (SelectField)tipoColumnas[column];
	        		selectField.setItemDefectoActivado(false);
					selectField.inicializarDatos(aux.getItems(), aux.getNombreAtributo(), aux.getNombreCampoClave());
					ArrayList arreglo = (ArrayList)itemSeleccionadoRender.get(column);
					if(arreglo.size()!=0){
						Object item = arreglo.get(row);
						selectField.setSelectedItem(item);
					}
					else{
						selectField.setSelectedIndex(0);
					}					
					selectField.setStyleName(nombreEstilo);
					selectField.setLayoutData(layoutData);
	        		componente = selectField;				       		
	        	}
        		else if (tipoColumnas[column] instanceof ListBox)
	        	{
	        		ListBox aux = (ListBox)tipoColumnas[column];
	        		ListBox listBox = new ListBox(aux.getWidth().getValue(), aux.getHeight().getValue());
					listBox.setItems(aux.getItems(), aux.getAtributo(), aux.getId());
					listBox.setStyleName(nombreEstilo);
					listBox.setLayoutData(layoutData);
	        		componente = listBox;				       		
	        	}
        		else if (tipoColumnas[column] instanceof DateField){
        			//DateField aux = (DateField)tipoColumnas[column];
        			DateField aux = new DateField();
        			ArrayList arreglo = (ArrayList)itemSeleccionadoRender.get(column);
        			if(arreglo.size()!=0){
						Date item = (Date)arreglo.get(row);
						Calendar calendario = Calendar.getInstance();
						calendario.setTime(item);
						aux.setSelectedDate(calendario);
					}
        			aux.setStyleName(nombreEstilo);
        			aux.setLayoutData(layoutData);
        			componente = aux;
        		}
        		else if (tipoColumnas[column] instanceof Button){
        			nextapp.echo2.app.Button boton = (Button)tipoColumnas[column];
        			nextapp.echo2.app.Button aux = new nextapp.echo2.app.Button();
        			try 
                	{
        				Integer fila = new Integer(row);
        				ActionListener[] arregloListeners = (ActionListener[])MethodUtils.invokeMethod(adapter,"getActionListenerBoton",fila);
        				aux.addActionListener(arregloListeners[column]);
        			} 
                	catch (Exception e) 
                	{       
                		System.out.println(e.getMessage());
        			}        			
        			aux.setStyleName(boton.getStyleName());					
        			componente = aux;
        		}
        	}
        	else
        	{
        		Label label;
        		if (value != null)
        		{
	        		label = new Label(value.toString());
        		}
        		else
        		{
        			label = new Label("");
        		}
        		//label.setLayoutData(layoutData);
    			label.setStyleName(nombreEstilo);
        		componente = label;
        	}
        	
        	return componente;
        }
    };

	private void configurarControles() {

		container = new Column();
		tabla = new PageableSortableTable();
		tabla.setDefaultHeaderRenderer(encabezadoTableCellRenderer);
		tabla.addActionListener(tablaActionListener);

		defaultListSelectionModel = new DefaultListSelectionModel();		
		tabla.setSelectionModel(defaultListSelectionModel);
		defaultListSelectionModel.setSelectionMode(ListSelectionModel.MULTIPLE_SELECTION);

		tabla.setStyleName("Obelisco.TablaDatos");
		tabla.setBorder(new BorderEx());
		tabla.setHeight(new ExtentEx("90%"));
		tabla.setWidth(new ExtentEx("100%"));
		add(container);
	}

	public AbstractTableAdapter getAdapter() {
		return adapter;
	}
	
	public void setAdapter(AbstractTableAdapter adapter) {
		this.adapter = adapter;
		container.removeAll();
		if ((adapter != null) && (adapter.getRowCount() != 0)) {
			container.add(tabla);
			modeloTabla = new DefaultPageableSortableTableModel(adapter);
			modeloTabla.addTableModelListener(tableModelListener);
			modeloTabla.setRowsPerPage(50);
			modeloTabla.setCurrentPage(0);			
			tabla.setModel(modeloTabla);
			tabla.setDefaultRenderer(Object.class, tableCellRenderer);
			tableScroller = new PageableTableNavigation(tabla);
			Alignment alineacion = new Alignment(Alignment.CENTER,Alignment.TOP);
			tableScroller.setAlignment(alineacion);
			container.add(tableScroller);
			TableColumnModel modeloColumna = tabla.getColumnModel();
			for (int i = 0; i < adapter.getColumnCount(); i++)
			{				
				TableColumn columna = modeloColumna.getColumn(i);				
				columna.setHeaderRenderer(encabezadoTableCellRenderer);				
			}
		} 
		else
		{
			Label lblSinDatos = new Label("No Hay Informacion Para Mostrar");
			lblSinDatos.setFont(new Font(null,1, new Extent(20)));
			ColumnLayoutData layoutData = new ColumnLayoutData();
			layoutData.setInsets(new Insets(null,new Extent(20, Extent.PERCENT),null,null));
			Alignment alineacion = new Alignment(Alignment.CENTER,Alignment.CENTER);
			layoutData.setAlignment(alineacion);
			lblSinDatos.setLayoutData(layoutData);			
			container.add(lblSinDatos);
		}
	}

	public void setFilasSeleccionadas(List listaObjetos)
	{
		for (int i=0; i < listaObjetos.size(); i++)
		{
			boolean isIgual = false;
			int posicion = 0;			
			for (int j=0; j < adapter.getRowCount(); j++)
			{
				Object objeto = adapter.getRow(j);				
				if (objeto.equals(listaObjetos.get(i)))
				{
					isIgual = true;
					posicion = j;
				}
			}
			if (isIgual)
			{
				defaultListSelectionModel.setSelectedIndex(posicion, true);
			}			
		}
		if(listaObjetos.size()>1){
			this.isMultiple = true;
		}
	}
	
 	public Object getFilasSeleccionadas() 
	{
		List seleccionados = new ArrayList();
		if (!isMultiple)
		{
			if (tabla.getSelectionModel().getMinSelectedIndex() >= 0) {
				return adapter.getRow(tabla.getSelectionModel().getMinSelectedIndex());
			} else {
				return null;
			}
		}
		else
		{
			for (int i = tabla.getSelectionModel().getMinSelectedIndex(); i <= tabla.getSelectionModel().getMaxSelectedIndex(); i++)
			{
				if (tabla.getSelectionModel().isSelectedIndex(i))
				{
					seleccionados.add(adapter.getRow(i));
				}
			}			
		}
		return seleccionados;
	}
		
	public boolean isMultiple() {
		return isMultiple;
	}
	
	public void setSelectionEnabled(boolean selectionEnabled){
		tabla.setSelectionEnabled(selectionEnabled);
	}
	
	public boolean isSelectionEnabled(){
		return tabla.isSelectionEnabled();
	}
	
	public void limpiarSeleccionTabla(){
		tabla.getSelectionModel().clearSelection();
		filaSeleccionada = -1;		
	}
		
	public boolean hayRegistrosSeleccionados(){
		if(tabla.getSelectionModel().getMinSelectedIndex() >= 0){
			return true;			
		}
		else{
			return false;
		}
	}	
	
	public void addTablaDatosActionListener(ActionListener tablaDatosActionListener){
		tabla.addActionListener(tablaDatosActionListener);		
	}
	
	public void setSeleccionMultiple(boolean modo)
	{
		if (modo)
		{
			defaultListSelectionModel.setSelectionMode(DefaultListSelectionModel.MULTIPLE_SELECTION);			
		}
		else
		{
			defaultListSelectionModel.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
		}
	}
	
	public boolean isSeleccionMultiple()
	{
		if (defaultListSelectionModel.getSelectionMode()==DefaultListSelectionModel.MULTIPLE_SELECTION)
		{
			return true;			
		}
		else if (defaultListSelectionModel.getSelectionMode()==DefaultListSelectionModel.SINGLE_SELECTION)
		{
			return false;
		}
		return false;
	}
	
	public List getListaObjetosRenderer(){
		List listaObjetos = new ArrayList();
		try {			
			String[] atributosColumnas = (String[])MethodUtils.invokeMethod(adapter,"getCOLUMN_ATTRIBUTES",null);
			Object[] tipoColumnas = (Object[])MethodUtils.invokeMethod(adapter,"getCOLUMN_TYPES",null);
			
			int cantidadRegistros = this.adapter.getRowCount();
			for (int i = 0; i < cantidadRegistros; i++) {
				Object objeto = this.adapter.getRow(i);
				int cantidadColumnas = this.adapter.getColumnCount();
				for (int j = 0; j < cantidadColumnas; j++) {
					if (tipoColumnas[j] instanceof SelectField){
						String nombreAtributo = atributosColumnas[j];
						SelectField combo = (SelectField)tabla.getCellComponent(j,i);
						Object itemSelecciondado = combo.getSelectedItem();
						MethodUtils.invokeMethod(objeto,"set"+nombreAtributo,itemSelecciondado);
		        	}
					else if (tipoColumnas[j] instanceof DateField){
						String nombreAtributo = atributosColumnas[j];
						DateField dateField = (DateField)tabla.getCellComponent(j,i);
						java.util.Date fecha = new Date(dateField.getSelectedDate().getTimeInMillis());
						MethodUtils.invokeMethod(objeto,"set"+nombreAtributo,fecha);					
					}
					else if (tipoColumnas[j] instanceof Button){
						//NO pasa NADA			
						System.out.println("SE METE POR AQUI");
					}
				}
				listaObjetos.add(objeto);
			}			
		}
		catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return (listaObjetos.size()==0)?null:listaObjetos;
	}
	
	public Component getComponente(int fila, int columna)
	{
		Component componente = tabla.getCellComponent(columna, fila);
		return componente;
	}
	
	private void modocebra(TableLayoutData c, int r) {
        if (r % 2 == 0) {
        	//c.setBackground(new Color(0xFFFFFF));
        	//c.setBackground(new Color(0x000000));
        } else {
        	//c.setBackground(new Color(0xEEF1F6));
        }
    }
	
	private String modocebra( int r) {
		String nombreEstilo = "";
        if (r % 2 == 0) {
        	nombreEstilo = "Obelisco.TablaDatos.Par";
        	//c.setBackground(new Color(0xFFFFFF));
        	//c.setBackground(new Color(0x000000));
        } else {
        	nombreEstilo = "Obelisco.TablaDatos.Impar";
        	//c.setBackground(new Color(0xEEF1F6));
        }
        return nombreEstilo;
    }


}


/*
Object espacio = (Object) listaHijos.get(numero.intValue());

if (espacio.getClass() == EspacioFisico.class)
{
EspacioFisico espacioFisico = (EspacioFisico) espacio;
if (espacioFisico.getTipoespaciofisico().getContenedor().equals("N")){
Object aux;
try {
aux = (EspacioFisico)BeanUtils.cloneBean(espacio);
objetoEntidad = aux; 
} catch (IllegalAccessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InstantiationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InvocationTargetException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NoSuchMethodException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
*/